package com.xiaoyang.billiards.architecture.common.exception;

import com.xiaoyang.billiards.architecture.common.Errors.Errors;
import lombok.Getter;

import java.io.Serial;
import java.io.Serializable;
import java.text.MessageFormat;

/**
 * @author 杨泽纬
 * @description 业务异常类
 * @serviceName BizException
 * @date 2023/11/16
 */
public class ServiceException extends RuntimeException implements Errors, Serializable {
    // 设置序列号
    @Serial
    private static final long serialVersionUID = 202011062L;

    private final int code;
    private final String msg;
    private final String errorCode;
    @Getter
    private final String[] msgParam;

    private ServiceException(int code, String errorCode, String msg) {
        super("[" + code + "]" + msg);
        this.code = code;
        this.msg = msg;
        this.errorCode = errorCode;
        this.msgParam = null;
    }

    private ServiceException(int code, String errorCode, String msg, Exception e, Object... args) {
        super("[" + code + "]" + msg, e);
        this.code = code;
        this.msg = msg;
        this.errorCode = errorCode;
        String[] param = new String[args.length];
        for (int i = 0; i < args.length; i++) {
            param[i] = String.valueOf(args[i]);
        }
        this.msgParam = param;
    }

    private ServiceException(int code, String errorCode, String msg, Object... args) {
        super("[" + code + "]" + msg);
        this.code = code;
        this.msg = msg;
        this.errorCode = errorCode;
        String[] param = new String[args.length];
        for (int i = 0; i < args.length; i++) {
            param[i] = String.valueOf(args[i]);
        }
        this.msgParam = param;
    }

    private ServiceException(int code, String errorCode, String msg, Exception e) {
        super("[" + code + "]" + msg, e);
        this.code = code;
        this.msg = msg;
        this.errorCode = errorCode;
        this.msgParam = null;
    }

    public ServiceException(Errors errors) {
        this(errors.getCode(), errors.getErrorCode(), errors.getMsg());
    }

    public ServiceException(Errors errors, Exception e) {
        this(errors.getCode(), errors.getErrorCode(), errors.getMsg(), e);
    }

    public ServiceException(Errors errors, Exception e, Object... args) {
        this(errors.getCode(), errors.getErrorCode(), MessageFormat.format(errors.getMsg(), args), e, args);
    }

    public ServiceException(Errors errors, Object... args) {
        this(errors.getCode(), errors.getErrorCode(), MessageFormat.format(errors.getMsg(), args), args);
    }


    @Override
    public int getCode() {
        return code;
    }

    @Override
    public String getMsg() {
        return msg;
    }

    @Override
    public String getErrorCode() {
        return errorCode;
    }
}
